package stone926.mods.more_enchantments.spawn;

import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.ShulkerEntity;
import net.minecraft.entity.mob.WitchEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import org.apache.commons.lang3.tuple.Triple;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;
import stone926.mods.more_enchantments.util.EnchantmentUtil;
import stone926.mods.more_enchantments.util.EntityUtil;
import stone926.mods.more_enchantments.util.ItemUtil;
import stone926.mods.more_enchantments.util.RandomUtil;

import java.util.Map;
import java.util.Random;


public final class EquipmentFitter {

  public static ItemStack getRandomWeaponForSkeleton(Random random) {
    return random.nextBoolean() ? getRandomAxeForSkeleton(random) : getRandomSwordForSkeleton(random);
  }

  public static ItemStack getRandomAxeForSkeleton(Random random) {
    return switch (random.nextInt(3)) {
      case 0 -> new ItemStack(Items.IRON_AXE);
      case 1 -> new ItemStack(Items.DIAMOND_AXE);
      case 2 -> new ItemStack(Items.NETHERITE_AXE);
      default -> ItemStack.EMPTY;
    };
  }

  public static ItemStack getRandomSwordForSkeleton(Random random) {
    return switch (random.nextInt(3)) {
      case 0 -> new ItemStack(Items.IRON_SWORD);
      case 1 -> new ItemStack(Items.DIAMOND_SWORD);
      case 2 -> new ItemStack(Items.NETHERITE_SWORD);
      default -> ItemStack.EMPTY;
    };
  }

//
//  public static ItemStack getRandomTool(Random random) {
//    return switch (random.nextInt(3)) {
//      case 0 -> getRandomShovel(random);
//      case 1 -> getRandomHoe(random);
//      case 2 -> getRandomPickaxe(random);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomShovel(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.WOODEN_SHOVEL);
//      case 1 -> new ItemStack(Items.STONE_SHOVEL);
//      case 2 -> new ItemStack(Items.IRON_SHOVEL);
//      case 3 -> new ItemStack(Items.GOLDEN_SHOVEL);
//      case 4 -> new ItemStack(Items.DIAMOND_SHOVEL);
//      case 5 -> new ItemStack(Items.NETHERITE_SHOVEL);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomHoe(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.WOODEN_HOE);
//      case 1 -> new ItemStack(Items.STONE_HOE);
//      case 2 -> new ItemStack(Items.IRON_HOE);
//      case 3 -> new ItemStack(Items.GOLDEN_HOE);
//      case 4 -> new ItemStack(Items.DIAMOND_HOE);
//      case 5 -> new ItemStack(Items.NETHERITE_HOE);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomPickaxe(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.WOODEN_PICKAXE);
//      case 1 -> new ItemStack(Items.STONE_PICKAXE);
//      case 2 -> new ItemStack(Items.IRON_PICKAXE);
//      case 3 -> new ItemStack(Items.GOLDEN_PICKAXE);
//      case 4 -> new ItemStack(Items.DIAMOND_PICKAXE);
//      case 5 -> new ItemStack(Items.NETHERITE_PICKAXE);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomWeapon(Random random) {
//    return switch (random.nextInt(3)) {
//      case 0 -> getRandomAxe(random);
//      case 1, 2 -> getRandomSword(random);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomAxe(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.WOODEN_AXE);
//      case 1 -> new ItemStack(Items.GOLDEN_AXE);
//      case 2 -> new ItemStack(Items.IRON_AXE);
//      case 3 -> new ItemStack(Items.DIAMOND_AXE);
//      case 4 -> new ItemStack(Items.NETHERITE_AXE);
//      case 5 -> new ItemStack(Items.STONE_AXE);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomSword(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.WOODEN_SWORD);
//      case 1 -> new ItemStack(Items.GOLDEN_SWORD);
//      case 2 -> new ItemStack(Items.IRON_SWORD);
//      case 3 -> new ItemStack(Items.DIAMOND_SWORD);
//      case 4 -> new ItemStack(Items.NETHERITE_SWORD);
//      case 5 -> new ItemStack(Items.STONE_SWORD);
//      default -> ItemStack.EMPTY;
//    };
//  }

//  public static ItemStack getRandomHelmet(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.LEATHER_HELMET);
//      case 1 -> new ItemStack(Items.GOLDEN_HELMET);
//      case 2 -> new ItemStack(Items.CHAINMAIL_HELMET);
//      case 3 -> new ItemStack(Items.IRON_HELMET);
//      case 4 -> new ItemStack(Items.DIAMOND_HELMET);
//      case 5 -> new ItemStack(Items.NETHERITE_HELMET);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomChestplate(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.LEATHER_CHESTPLATE);
//      case 1 -> new ItemStack(Items.GOLDEN_CHESTPLATE);
//      case 2 -> new ItemStack(Items.CHAINMAIL_CHESTPLATE);
//      case 3 -> new ItemStack(Items.IRON_CHESTPLATE);
//      case 4 -> new ItemStack(Items.DIAMOND_CHESTPLATE);
//      case 5 -> new ItemStack(Items.NETHERITE_CHESTPLATE);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomLegging(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.LEATHER_LEGGINGS);
//      case 1 -> new ItemStack(Items.GOLDEN_LEGGINGS);
//      case 2 -> new ItemStack(Items.CHAINMAIL_LEGGINGS);
//      case 3 -> new ItemStack(Items.IRON_LEGGINGS);
//      case 4 -> new ItemStack(Items.DIAMOND_LEGGINGS);
//      case 5 -> new ItemStack(Items.NETHERITE_LEGGINGS);
//      default -> ItemStack.EMPTY;
//    };
//  }
//
//  public static ItemStack getRandomBoot(Random random) {
//    return switch (random.nextInt(6)) {
//      case 0 -> new ItemStack(Items.LEATHER_BOOTS);
//      case 1 -> new ItemStack(Items.GOLDEN_BOOTS);
//      case 2 -> new ItemStack(Items.CHAINMAIL_BOOTS);
//      case 3 -> new ItemStack(Items.IRON_BOOTS);
//      case 4 -> new ItemStack(Items.DIAMOND_BOOTS);
//      case 5 -> new ItemStack(Items.NETHERITE_BOOTS);
//      default -> ItemStack.EMPTY;
//    };
//  }

  public static void equipBow(MobEntity mob, Random random) {
    int rr = random.nextInt(25);
    ItemStack stack;
    if (rr <= 18) {
      stack = EnchantmentUtil.enchant(new ItemStack(Items.BOW), MobEnchantmentMaps.BOW(random), random);
    } else if (rr <= 21) {
      stack = EnchantmentUtil.enchant(new ItemStack(MoreEnchantmentsMod.WITHER_SKULL_BOW), MobEnchantmentMaps.WITHER_SKULL_BOW(), random);
    } else if (rr <= 23) {
      stack = EnchantmentUtil.enchant(new ItemStack(MoreEnchantmentsMod.FIREBALL_BOW), MobEnchantmentMaps.FIREBALL_BOW(), random);
    } else {
      stack = EnchantmentUtil.enchant(new ItemStack(MoreEnchantmentsMod.SHULKER_BOW), MobEnchantmentMaps.SHULKER_BOW(), random);
    }
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, stack, 0.4F);
  }

  public static void equipWeapon(MobEntity mob, Random random) {
    ItemStack weaponStack = new ItemStack(ItemUtil.getRandomWeapon(random));
    RandomUtil.runIfPossible(0.75, random, () -> EnchantmentUtil.enchant(weaponStack, MobEnchantmentMaps.WEAPON(), 0.4F, random));
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, weaponStack, 0.5F);
  }

  public static void equipTrident(MobEntity mob, Random random) {
    ItemStack trident = new ItemStack(Items.TRIDENT);
    EnchantmentUtil.enchant(trident, MobEnchantmentMaps.TRIDENT(), 0.7F, random);
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, trident, 0.6F);
  }

  public static void equipTurtleHelmet(MobEntity mob, Random random) {
    ItemStack turtle = new ItemStack(Items.TURTLE_HELMET);
    EnchantmentUtil.enchant(turtle, MobEnchantmentMaps.TURTLE_HELMET(), 1, random);
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.HEAD, turtle, 1);
  }

  public static void equipWeaponForZombifiedPiglin(MobEntity mob, Random random) {
    ItemStack weaponStack = new ItemStack(ItemUtil.getRandomWeapon(random));
    if (RandomUtil.isPossible(0.75, random)) {
      EnchantmentUtil.enchant(weaponStack, MobEnchantmentMaps.ZOMBIFIED_PIGLIN_WEAPON(), 0.4F, random);
    }
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, weaponStack, 0.5F);
  }

  public static void equipArmorForZombifiedPiglin(MobEntity mob, Random random) {
    Map<Enchantment, Triple<Integer, Integer, Double>> ench = MobEnchantmentMaps.ARMOR(random);
    RandomUtil.runFunctionsIfPossible(
      0.35, random,
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.HEAD, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomHelmet(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.CHEST, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomChestplate(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.LEGS, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomLeggings(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.FEET, EnchantmentUtil.enchant(EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomBoots(random)), MoreEnchantmentsMod.SOLIDIFY_WALKER, RandomUtil.nextInt(1, 14, random)), ench, 0.34F, random), 0.4F)
    );
  }

  public static void equipTool(MobEntity mob, Random random) {
    ItemStack tool = new ItemStack(ItemUtil.getRandomTool(random));
    if (RandomUtil.isPossible(0.75, random)) {
      EnchantmentUtil.enchant(tool, MobEnchantmentMaps.TOOL(random), 0.6F, random);
    }
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, tool, 0.5F);
  }

  public static void equipWeaponForSkeleton(MobEntity mob, Random random) {
    ItemStack weaponStack = getRandomWeaponForSkeleton(random);
    EnchantmentUtil.enchant(weaponStack, MobEnchantmentMaps.SKELETON_WEAPON(), 0.34F, random);
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.MAINHAND, weaponStack, 0.4F);
  }

  public static void equipArmor(MobEntity mob, Random random) {
    Map<Enchantment, Triple<Integer, Integer, Double>> ench = MobEnchantmentMaps.ARMOR(random);
    RandomUtil.runFunctionsIfPossible(
      0.34, random,
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.HEAD, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomHelmet(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.CHEST, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomChestplate(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.LEGS, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomLeggings(random)), ench, 0.34F, random), 0.4F),
      () -> EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.FEET, EnchantmentUtil.enchant(new ItemStack(ItemUtil.getRandomBoots(random)), ench, 0.34F, random), 0.4F)
    );
  }

  public static void equipShulkerBox(ShulkerEntity shulker, Random random) {
    EntityUtil.equipStackAndSetDropChance(shulker, EquipmentSlot.FEET, ShulkerBoxBlock.getItemStack(shulker.getColor()), 0.2F);
  }

  public static void equipElytra(MobEntity mob, Random random) {
    ItemStack stack = new ItemStack(Items.ELYTRA);
    if (RandomUtil.isPossible(0.3, random)) {
      stack.addEnchantment(Enchantments.UNBREAKING, RandomUtil.nextInt(1, Enchantments.UNBREAKING.getMaxLevel() + 1, random));
      if (RandomUtil.isPossible(0.5, random)) { stack.addEnchantment(Enchantments.MENDING, 1); }
    } else if (RandomUtil.isPossible(0.3, random)) {
      stack.addEnchantment(MoreEnchantmentsMod.UNBREAKABLE, 2);
    }
    EntityUtil.equipStackAndSetDropChance(mob, EquipmentSlot.HEAD, stack, 0.2F);
  }

  public static void equipArmorForWitch(WitchEntity witch, Random random) {
    ItemStack stack = EnchantmentUtil.enchant(new ItemStack(Items.NETHERITE_CHESTPLATE), MobEnchantmentMaps.WITCH_ARMOR(), 0.4F, random);
    EntityUtil.equipStackAndSetDropChance(witch, EquipmentSlot.CHEST, stack, 0.7F);
  }

  public static void equipArmorForPiglin(MobEntity piglin, Random random) {
    if (RandomUtil.isPossible(0.2, random)) {
      EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.OFFHAND, new ItemStack(Items.ENCHANTED_GOLDEN_APPLE), 1F);
    }
    EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.MAINHAND, EnchantmentUtil.enchant(new ItemStack(Items.GOLDEN_SWORD), MobEnchantmentMaps.WEAPON(), 0.5, random), 0.3F);
    RandomUtil.runFunctionsIfPossible(
      0.6, random,
      () -> EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.CHEST, EnchantmentUtil.enchant(new ItemStack(Items.GOLDEN_CHESTPLATE), MobEnchantmentMaps.ARMOR(random), 0.5, random), 0.2F),
      () -> EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.LEGS, EnchantmentUtil.enchant(new ItemStack(Items.GOLDEN_LEGGINGS), MobEnchantmentMaps.ARMOR(random), 0.5, random), 0.2F),
      () -> EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.HEAD, EnchantmentUtil.enchant(new ItemStack(Items.GOLDEN_HELMET), MobEnchantmentMaps.ARMOR(random), 0.5, random), 0.2F),
      () -> EntityUtil.equipStackAndSetDropChance(piglin, EquipmentSlot.FEET, EnchantmentUtil.enchant(new ItemStack(Items.GOLDEN_BOOTS), MobEnchantmentMaps.ARMOR(random), 0.5, random), 0.2F)
    );
  }

}
